<template>
	<el-form :model="user" :rules="rules" ref="loginRef">
		<el-form-item prop="username">
			<el-input v-model="user.username" placeholder="用户名">
				<template #prefix>
					<el-icon><User /></el-icon>
				</template>
			</el-input>
		</el-form-item>

		<el-form-item prop="password">
			<el-input v-model="user.password" type="password" show-password placeholder="密码">
				<template #prefix>
					<el-icon><Lock /></el-icon>
				</template>
			</el-input>
		</el-form-item>

		<el-form-item prop="confirmPsw">
			<el-input @keyup.enter="onLogin(loginRef)" v-model="user.confirmPsw" type="password" show-password placeholder="确认密码">
				<template #prefix>
					<el-icon><Lock /></el-icon>
				</template>
			</el-input>
		</el-form-item>

		<el-form-item :prop="count >= 3 ? 'verifyCode' : ''" v-show="count >= 3">
			<el-input @keyup.enter="onLogin(loginRef)" v-model="user.verifyCode" type="text" placeholder="验证码">
				<template #suffix>
					<span v-html="veryCode.data" @click="getVeryCode"></span>
				</template>
			</el-input>
		</el-form-item>
		<!-- 记住密码  -->
		<el-form-item prop="remmberPsw">
			<el-checkbox v-model="user.remmberPsw" label="记住密码"></el-checkbox>
		</el-form-item>
		<el-form-item>
			<el-button :loading="isLoading" type="primary" @click="onLogin(loginRef)">登录</el-button>
			<a href="#" @click="$emit('bindChange', false)">手机号登录</a>
		</el-form-item>
	</el-form>
</template>

<script setup lang="ts">
import { User, Lock } from '@element-plus/icons-vue'

import { ref, type Ref, onMounted } from 'vue'
import { ElMessage, FormInstance } from 'element-plus'
import { useRouter } from 'vue-router'
import sha256 from 'js-sha256'
import { saveUserToStore } from '@/common/useStore'
import { useMenuStore } from '@/stores/modules/menu'
import { ACCESS_TOKEN, REFRESH_TOKEN } from '@/utils/constant'
import { encrypt, decrypt } from '@/utils'
import { api } from '@/api/index'

const { RequesetVeryCode, RequestLogin, RequestManagerLogAdd } = api
defineEmits(['bindChange'])

interface IUser {
	username: string
	password: string
	confirmPsw: string
	verifyCode: string
	remmberPsw: boolean
}

const user: Ref<IUser> = ref({
	username: '',
	password: '',
	confirmPsw: '',
	verifyCode: '',
	remmberPsw: true
})
/**
 * 确定密码方法
 */
const validatePass2 = (rule: any, value: any, callback: any) => {
	if (value === '') {
		callback(new Error('请再次输入密码'))
	} else if (value !== user.value.password) {
		callback(new Error('两次输入密码不匹配!'))
	} else {
		callback()
	}
}
let count = ref<number>(0) //记录三次出错显示验证码

const loginRef = ref<FormInstance>()
const isLoading: Ref<boolean> = ref(false)
const rules = ref({
	username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
	password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
	verifyCode: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
	confirmPsw: [{ validator: validatePass2, trigger: 'blur' }]
})
const veryCode: Ref<{ data: string; code: string }> = ref({
	data: '',
	code: ''
})
const router = useRouter()
const menuStore = useMenuStore()

onMounted(() => {
	getVeryCode()
	showUserInfo()
})

/**
 * 生成验证码
 */
const getVeryCode = async () => {
	const data = await RequesetVeryCode()
	const { resultCode, resultInfo } = data
	if (resultCode === 1) {
		const { code, data } = resultInfo
		veryCode.value.data = data
		veryCode.value.code = code
	}
}

/**
 * 校验验证码
 */
const checkVeriyCode = () => {
	const inputCode = user.value.verifyCode
	if (inputCode !== veryCode.value.code) {
		ElMessage.error('验证码出错!')
		return true
	}
	return false
}

/**
 * 登录
 * @param formEl
 */
const onLogin = (formEl: FormInstance | undefined) => {
	console.log('onLogin >>> ')

	// 表单验证
	if (!formEl) return
	formEl.validate(valid => {
		if (valid) {
			if (count.value >= 3 && checkVeriyCode()) {
				return
			}
			bindLogin()
		} else {
			ElMessage.error('表单验证出错!')
		}
	})
}

const bindLogin = async () => {
	isLoading.value = true // 加载效果
	const username = user.value.username
	const password = user.value.password
	let psw = sha256(password)
	try {
		const data = await RequestLogin(username, psw)
		const { resultCode, resultInfo, token, refrechToken } = data

		if (resultCode === 1) {
			// 登录成功之后的业务
			// 1. 保存token, 统一登录身份认证（路由拦截）, 网络axios请求拦截(后端根据请求头中携带的token，决定是否返回接口数据给你)
			localStorage.setItem(ACCESS_TOKEN, token as string)
			localStorage.setItem(REFRESH_TOKEN, refrechToken as string)

			// 保存角色id
			localStorage.setItem('ROLE_ID', resultInfo.role_id)
			// 2. 保存用户信息(昵称和头像) 主界面显示
			saveUserToStore({
				mid: resultInfo.m_id,
				nick: resultInfo.nick,
				url: resultInfo.headerimg
			})
			// 3. 记住密码
			onRemmberPassword()
			// 3.保存日志
			addSysLog(resultInfo.nick)
			// 4. 根据角色id获取动态权限菜单列表和按钮资源权限列表
			menuStore.saveMenuList(resultInfo.role_id).then(() => {
				// 登录成功进入主界面
				router.replace('/home')
			})
		} else {
			ElMessage.error('用户名或密码出错!')
			count.value++
		}
		isLoading.value = false
	} catch (error) {
		console.log(error)
		count.value++
		isLoading.value = false
	}
}

/**
 * 记住密码
 */
const onRemmberPassword = () => {
	if (user.value.remmberPsw) {
		const text = encrypt(user.value.password) // 加密
		localStorage.setItem(
			'USER_INFO',
			JSON.stringify({
				username: user.value.username,
				password: text
			})
		)
	} else {
		localStorage.removeItem('USER_INFO')
	}
}

/**
 * 显示账户到表单
 */
const showUserInfo = () => {
	const userInfo = localStorage.getItem('USER_INFO')
	if (userInfo) {
		const account = JSON.parse(userInfo)
		const psw = decrypt(account.password) // 解密
		user.value.username = account.username
		user.value.password = psw
		user.value.confirmPsw = psw
	}
}

/**
 * 添加日志
 */
const addSysLog = async (nick: string) => {
	const content = '登录系统成功'
	const ip = localStorage.getItem('IP') || (window as any).returnCitySN['cip']
	const data = await RequestManagerLogAdd(content, nick, ip)
	console.log('data ', data)
}
</script>

<style scoped lang="scss">
form {
	background-color: white;
	border-radius: 8px;
	padding: 30px 25px;
	.el-button {
		width: 100%;
		margin-top: 24px;
	}
}
</style>
